home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 June: Reference Library / Dev.CD Jun 94.toast / Periodicals / develop / develop Issue 9 / develop 9 code / Tracks / dumptracks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-16  |  26.9 KB  |  1,281 lines  |  [TEXT/MPS ]

  1. #include "DumpTracks.h"
  2. #include <Stdio.h>
  3. #include <Files.h>
  4. #include <Folders.h>
  5.  
  6. #include <String.h>
  7. #include "Packages.h"
  8. #ifndef THINK_C
  9. #include <Strings.h>
  10. #include <Resources.h>
  11. #include <Memory.h>
  12. #include "Types.h"
  13. #include "Errors.h"
  14. #include "OSUtils.h"
  15. #include "StdLib.h"
  16. #include "ToolUtils.h"
  17. #endif
  18.  
  19. shex gReadBuff[1024];
  20. shex gReadBuffSize;
  21. Ptr fRecordBuffer;
  22. char printBuff[1000];
  23. char *fPrintBuffer;
  24. char gFileName[100];
  25. short    lastDiagID =-1;    
  26. short    gPrefsVRefNum;
  27. Boolean    gVerboseMode =1;
  28.  
  29. #ifndef THINK_C
  30. main(int argc, char **argv)
  31. #else
  32. main()
  33. #endif
  34. {
  35. snum result;
  36. short refNum;
  37. SysEnvRec Environment;
  38. short    SysFolderRefNum;
  39. short PrefsResRefNum, infoFileRefNum=-1;
  40. Handle    driverName;
  41.         
  42.     fRecordBuffer = (Ptr) gReadBuff;
  43.     fPrintBuffer = printBuff;
  44.     gReadBuffSize = sizeof(gReadBuff);
  45.  
  46.     (void) SysEnvirons(1, &Environment);
  47.     SysFolderRefNum = Environment.sysVRefNum;        // Get the sys folder vref
  48.     gPrefsVRefNum = GetFolderVol(kPreferencesFolderType);
  49.     if (gPrefsVRefNum == 0) 
  50.     {
  51.         printf("Error finding preference folder\n");
  52.         gPrefsVRefNum = SysFolderRefNum;
  53.     }
  54.     
  55.     strcpy(gFileName,(char *)"\pTracks Prefs");
  56.     
  57. #ifndef THINK_C
  58.     ParseArgs(argc, argv);
  59. #endif
  60.  
  61.     PrefsResRefNum = OpenRFPerm(gFileName, gPrefsVRefNum, fsRdWrPerm);
  62.     result = ResError();
  63.     if (result != 0) 
  64.     {
  65.         printf("Abort: prefs file get Error #%d", result);
  66.         exit(3);
  67.     }
  68.  
  69.     result = FSOpen(gFileName, 0, &refNum);
  70.     if (result != noErr)
  71.         {
  72.             SetVol(nil, gPrefsVRefNum);
  73.             result = FSOpen(gFileName,0,&refNum);    
  74.         }
  75.  
  76.     if (result == noErr)
  77.         {        
  78.  
  79.         p2cstr(gFileName);
  80.         
  81.         driverName = GetResource('kDRp', 128);
  82.         if (driverName!=nil)
  83.         {
  84.             infoFileRefNum = OpenRFPerm(*driverName, SysFolderRefNum, fsRdWrPerm);
  85.             if (infoFileRefNum == -1) 
  86.                 infoFileRefNum = OpenRFPerm(*driverName, GetFolderVol(kExtensionFolderType), fsRdWrPerm);
  87.             if (infoFileRefNum == -1) 
  88.                 infoFileRefNum = OpenRFPerm(*driverName, GetFolderVol(kControlPanelFolderType), fsRdWrPerm);
  89.             if (infoFileRefNum == -1) 
  90.                 printf("Warning:  Couldnt load name list\n");
  91.             ReleaseResource(driverName);
  92.         } else printf("Pref File data not found");
  93.  
  94.         //if (gVerboseMode)    
  95.         //    printf("Dumping file %s   \n", gFileName);
  96.  
  97.         }
  98.  
  99.     TypeDumpSetUp(SysFolderRefNum);    // Set up template (format06) printing (reads in 'mxwt' resources)
  100.         
  101.     result = ReadFileRecords(refNum);
  102.     if (result == noErr || result == eofErr)
  103.         if (gVerboseMode)    printf("\n--- End of dump ---\n");
  104.     else
  105.         {
  106.         printf("--- Dump terminated, error = %d ---\n", result);
  107.         if (result == -43) printf("(File not found)\n");
  108.         }
  109.         
  110.     if (infoFileRefNum != -1) 
  111.         CloseResFile(infoFileRefNum);
  112.     TypeDumpCloseDown();
  113.     (void) FSClose(refNum);
  114.     CloseResFile(PrefsResRefNum);
  115.     exit(0);
  116. }
  117.  
  118. short GetFolderVol(OSType type)
  119. {
  120. WDPBRec        wdParamBlock;        /*param block to set up working directory*/
  121. short         result;
  122. short         prefVRef;
  123. long         prefDirID;
  124.  
  125.     result=FindFolder(kOnSystemDisk, type, true, &prefVRef, &prefDirID);
  126.     if (result == 0)
  127.     {
  128.         wdParamBlock.ioCompletion = NULL;
  129.         wdParamBlock.ioNamePtr = NULL;
  130.         wdParamBlock.ioVRefNum = prefVRef;
  131.         wdParamBlock.ioWDDirID = prefDirID;
  132.         result=PBOpenWD(&wdParamBlock, false);
  133.         if (result == 0)
  134.             return wdParamBlock.ioVRefNum;
  135.     }
  136.     return 0;
  137. }
  138.  
  139.  
  140. void CopyEbcdicToAscii(unsigned char *ebcdic, unsigned char *toAscii,
  141.  unsigned short dataLength)
  142.     {
  143.  
  144.     unsigned char *asciiArray;
  145.     
  146.     // String pointer used to avoid data initialization...
  147.  
  148.     asciiArray = (unsigned char *)
  149.         "\000\001\002\003\234\011\206\177"
  150.         "\227\215\216\013\014\015\016\017"
  151.         "\020\021\022\023\235\205\010\207"
  152.         "\030\031\222\217\034\035\036\037"
  153.         "\200\201\202\203\204\012\027\033"
  154.         "\210\211\212\213\214\005\006\007"
  155.         "\220\221\026\223\224\225\226\004"
  156.         "\230\231\232\233\024\025\236\032"
  157.         "\040\240\241\242\243\244\245\246"
  158.         "\247\250\133\056\074\050\053\041"
  159.         "\046\251\252\253\254\255\256\257"
  160.         "\260\261\135\044\052\051\073\136"
  161.         "\055\057\262\263\264\265\266\267"
  162.         "\270\271\174\054\045\137\076\077"
  163.         "\272\273\274\275\276\277\300\301"
  164.         "\302\140\072\043\100\047\075\042"
  165.         "\303\141\142\143\144\145\146\147"
  166.         "\150\151\304\305\306\307\310\311"
  167.         "\312\152\153\154\155\156\157\160"
  168.         "\161\162\313\314\315\316\317\320"
  169.         "\321\176\163\164\165\166\167\170"
  170.         "\171\172\322\323\324\325\326\327"
  171.         "\330\331\332\333\334\335\336\337"
  172.         "\340\341\342\343\344\345\346\347"
  173.         "\173\101\102\103\104\105\106\107"
  174.         "\110\111\350\351\352\353\354\355"
  175.         "\175\112\113\114\115\116\117\120"
  176.         "\121\122\356\357\360\361\362\363"
  177.         "\134\237\123\124\125\126\127\130"
  178.         "\131\132\364\365\366\367\370\371"
  179.         "\060\061\062\063\064\065\066\067"
  180.         "\070\071\372\373\374\375\376\377";
  181.  
  182.     
  183.     while (dataLength > 0)
  184.         {
  185.         *toAscii++ = asciiArray[(*ebcdic++)];
  186.         dataLength--;
  187.         }
  188.     
  189.     return;
  190.     
  191.     }
  192.  
  193. CopyPStr(char *src, char *dst)
  194. {
  195. register char x,len;
  196.     len = *src;
  197.     
  198.     for (x=0;x<=len;x++)
  199.         *dst++ = *src++;
  200.  
  201. }
  202.  
  203. snum DecodeSym(char *stringBuffer, char *symbol, Boolean showTypeInfo, Ptr stackdataPtr)
  204.     {
  205.     char *funcNamePtr;
  206.     char *classNamePtr;
  207.     snum funcNameLength;
  208.     snum classNameLength;
  209.     char *typeInfoPtr;
  210.     char *p, *copy;
  211.     snum len;
  212.     snum i, j;
  213.     char *modUstr = "unsigned";
  214.     char modUstrlen = 8;
  215.     char *argPtr;
  216.     char *typeNamePtr;
  217.     char typeNameLen;
  218.     snum typesize;
  219.     char *argNamePtr[32];
  220.     snum argNameLen[32];
  221.     snum argCount;
  222.     snum argMod[32];
  223.     snum argSize[32];
  224.     snum temp1;
  225.     snum temp2;
  226.     char tempc1;
  227.     char tempc2;
  228.  
  229.     
  230.     // function name:
  231.     
  232.     if (*symbol == 0)
  233.         {
  234.             return(0);
  235.         }
  236.     funcNamePtr = symbol;
  237.     funcNameLength = 0;
  238.     
  239.     p = funcNamePtr;
  240.     while ((*p != '_') && (*p != 0))
  241.         {
  242.         funcNameLength++;
  243.         p++;
  244.         }
  245.     
  246.     // if "__" follows the function name, then look for class name or type info
  247.     
  248.     classNameLength = 0;
  249.     typeInfoPtr = NULL;
  250.     
  251.     if ((*p == '_') && (*(p + 1) == '_'))
  252.         {
  253.         
  254.         p += 2; // skip past the "__"
  255.         
  256.         // if the next character is not "F", then get the class name
  257.         
  258.         if (*p != 'F')
  259.             {
  260.             len = 0;
  261.             while ((*p <= '9') && (*p >= '0'))
  262.                 {
  263.                 if (len != 0)
  264.                     len = len * 10;
  265.                 len += *p - '0';
  266.                 p++;
  267.                 }
  268.             classNamePtr = p;
  269.             classNameLength = len;
  270.             p += len;
  271.             }
  272.         
  273.         // if the next character is "F", then get the type info
  274.         
  275.         if (*p == 'F')
  276.             typeInfoPtr = p;
  277.         
  278.         }
  279.  
  280.  
  281. // TEST---
  282.     len = 0;
  283.     copy = stringBuffer;
  284.     if (classNameLength > 0)
  285.         {
  286.         for (i = 0; i < classNameLength; i++)
  287.             *copy++ = *(classNamePtr + i);
  288.         *copy++ = ':';
  289.         *copy++ = ':';
  290.         len += 2 + classNameLength;
  291.         }
  292.     if (funcNameLength > 0)
  293.         {
  294.         for (i = 0; i < funcNameLength; i++)
  295.             *copy++ = *(funcNamePtr + i);
  296.         len += funcNameLength;
  297.         }
  298.  
  299.     if ((typeInfoPtr != NULL) && showTypeInfo)
  300.         {
  301.         argPtr = typeInfoPtr + 1;    // skip the "F"
  302.         
  303.         argCount = 0;
  304.         if (classNameLength > 0)
  305.             {
  306.             argCount = 1;
  307.             argNamePtr[0] = "this";
  308.             argNameLen[0] = 4;
  309.             argMod[0] = 1; // this*=
  310.             }
  311.         argMod[argCount] = 0;
  312.         argNameLen[argCount] = 0;
  313.  
  314.         typeNamePtr = NULL;
  315.         typeNameLen = 0;
  316.         typesize = 0;
  317.         
  318.         while ((*argPtr != 0) && (argCount < 16))
  319.             {
  320.             
  321.             switch (*argPtr)
  322.                 {
  323.               case 'v' :
  324.                   typeNamePtr = "void";
  325.                 typeNameLen = 4;
  326.                 typesize = 0;
  327.                 argPtr++;
  328.                   break;
  329.               case 'c' :
  330.                   typeNamePtr = "char";
  331.                 typeNameLen = 4;
  332.                 typesize = 4;    // 4 bytes on stack ???? ( unless pascal????)
  333.                 argPtr++;
  334.                   break;
  335.               case 's' :
  336.                   typeNamePtr = "short";
  337.                 typeNameLen = 5;
  338.                 typesize = 4;    // seems to be 4 bytes on stack (unless pascal???)
  339.                 argPtr++;
  340.                 break;
  341.               case 'i' :
  342.                   typeNamePtr = "int";
  343.                 typeNameLen = 3;
  344.                 typesize = 4;
  345.                 argPtr++;
  346.                 break;
  347.               case 'l' :
  348.                   typeNamePtr = "long";
  349.                 typeNameLen = 4;
  350.                 typesize = 4;
  351.                 argPtr++;
  352.                 break;
  353.               case 'e' :
  354.                   typeNamePtr = "...";
  355.                 typeNameLen = 3;
  356.                 typesize = 0;
  357.                 argPtr++;
  358.                 break;
  359.               case 'P' :
  360.                 if ((argMod[argCount] & 1) == 0)
  361.                     argMod[argCount] |= 1;    // type*
  362.                 else if ((argMod[argCount] & 2) == 0)
  363.                     argMod[argCount] |= 2;    // type**
  364.                 else
  365.                     argMod[argCount] |= 16; // unknown
  366.                 argPtr++;
  367.                 break;
  368.               case 'U' :
  369.                   argMod[argCount] |= 8;        // unsigned
  370.                 argPtr++;
  371.                 break;
  372.               case 'F' :
  373.                   if (argMod[argCount] & 1)
  374.                     {
  375.                     argMod[argCount] &= 0xfffe; // clear (type*) pointer
  376.                       argMod[argCount] |= 32;        // pointer-to-function
  377.                     }
  378.                 else
  379.                     argMod[argCount] |= 16; // unknown
  380.                 argPtr++;
  381.                 break;
  382.               case '_' :
  383.                   if (argMod[argCount] & 32)        // for pointer-to-function
  384.                     {
  385.                       argMod[argCount] |= 64;     // display of return value not implemented yet
  386.                     typeNamePtr = NULL;
  387.                     }
  388.                 else
  389.                     argMod[argCount] |= 16; // unknown
  390.                 argPtr++;
  391.                 break;
  392.               case '0' :
  393.               case '1' :
  394.               case '2' :
  395.               case '3' :
  396.               case '4' :
  397.               case '5' :
  398.               case '6' :
  399.               case '7' :
  400.               case '8' :
  401.               case '9' :
  402.                   typeNameLen = *argPtr - '0';
  403.                 if ((*(argPtr + 1) >= '0') && (*(argPtr + 1) <= '9'))
  404.                     {
  405.                     argPtr++;
  406.                     typeNameLen = 10 * typeNameLen;
  407.                     typeNameLen += *argPtr - '0';
  408.                     }
  409.                 argPtr++;
  410.                 typeNamePtr = argPtr;
  411.                 argPtr += typeNameLen;
  412.                 typesize = 4;
  413.                 break;
  414.               case 'T' :        // Tx - same as argument x
  415.               case 'N' :
  416.                   if (*argPtr == 'N')
  417.                     {
  418.                     argPtr++;
  419.                     temp1 = *(argPtr + 1) - '0';
  420.                     }
  421.                 else
  422.                     temp1 = 1;
  423.                 argPtr++;
  424.                 
  425.                 for (i = 0; i < temp1; i++)
  426.                     {
  427.                     temp2 = *argPtr - '0';
  428.                     argPtr++;
  429.                     if (classNameLength == 0)
  430.                         temp2--; // arg n is array index n-1 (unless class "this" present)
  431.                     argNamePtr[argCount] = argNamePtr[temp2];
  432.                     argNameLen[argCount] = argNameLen[temp2];
  433.                     argMod[argCount] = argMod[temp2];
  434.                     argSize[argCount] = argSize[temp2];
  435.                     argCount++;
  436.                     argMod[argCount] = 0;
  437.                     }
  438.                 break;
  439.               default:
  440.                   argMod[argCount] |= 16; // unknown
  441.                 argPtr++;
  442.                 break;
  443.                 }
  444.             
  445.             if ((typeNamePtr != NULL) && 
  446.                 (((argMod[argCount] & 32) == 0) || (*argPtr != '_')) )
  447.                 {
  448.                 argNamePtr[argCount] = typeNamePtr;
  449.                 argNameLen[argCount] = typeNameLen;
  450.                 argSize[argCount] = typesize;
  451.                 argCount++;
  452.                 argMod[argCount] = 0;
  453.                 typeNamePtr = NULL;
  454.                 typeNameLen = 0;
  455.                 }
  456.             
  457.             }
  458.         
  459.         *copy++ = '(';
  460.         len++;
  461.         for (i = 0; i < argCount; i++)
  462.             {
  463.             if (argMod[i] & 8)
  464.                 {
  465.                 for (j = 0; j < modUstrlen; j++)
  466.                     *copy++ = *(modUstr + j);
  467.                 *copy++ = ' ';
  468.                 len += (1 + modUstrlen);
  469.                 }
  470.  
  471.             for (j = 0; j < argNameLen[i]; j++)
  472.                 *copy++ = *(argNamePtr[i] + j);
  473.             len += argNameLen[i];
  474.  
  475.             if (argMod[i] & 1)
  476.                 {
  477.                 argSize[i] = 4;
  478.                 *copy++ = '*';
  479.                 len++;
  480.                 }
  481.             if (argMod[i] & 2)
  482.                 {
  483.                 argSize[i] = 4;
  484.                 *copy++ = '*';
  485.                 len++;
  486.                 }
  487.             if (argMod[i] & 16)
  488.                 {
  489.                 *copy++ = '?';
  490.                 len++;
  491.                 }
  492.             if (argMod[i] & 32)
  493.                 {
  494.                 *copy++ = ' ';
  495.                 *copy++ = '(';
  496.                 *copy++ = '*';
  497.                 *copy++ = ' ';
  498.                 *copy++ = '?';
  499.                 *copy++ = ')';
  500.                 *copy++ = '(';
  501.                 *copy++ = ')';
  502.                 len += 8;
  503.                 }
  504.             if ((stackdataPtr != NULL) && (argSize[i] > 0))
  505.                 {
  506.                 *copy++ = '=';
  507.                 len++;
  508.                 for (j = 0; j < argSize[i]; j++)
  509.                     {
  510.                     tempc1 = (*stackdataPtr & 0xf0) >> 4;
  511.                     tempc2 = *stackdataPtr & 0x0f;
  512.                     if (tempc1 < 10)
  513.                         *copy++ = '0' + tempc1;
  514.                     else
  515.                         *copy++ = 'A' + (tempc1 - 10);
  516.                     if (tempc2 < 10)
  517.                         *copy++ = '0' + tempc2;
  518.                     else
  519.                         *copy++ = 'A' + (tempc2 - 10);
  520.                     len += 2;
  521.                     stackdataPtr++;
  522.                     }
  523.                 }
  524.             if (i < (argCount - 1))
  525.                 {
  526.                 *copy++ = ',';
  527.                 *copy++ = ' ';
  528.                 len += 2;
  529.                 }
  530.             }
  531.         *copy++ = ')';
  532.         len++;
  533.             
  534.         }
  535.         
  536.     *copy = 0;    // null terminated string
  537.     
  538.         
  539.     
  540.     return(len);
  541.     
  542. }
  543.         
  544.  
  545. DumpBytes(Ptr p, short s)
  546.     {
  547.     int i;
  548.     Ptr addr;
  549.     
  550.     addr = p;
  551.     for (i = 0; i < s; i++)
  552.         {
  553.         if (i % 32 == 0)
  554.             printf("%08x: ", p - addr);
  555.         
  556.         printf("%02x", *p++ & 0x0ff);
  557.         
  558.         if (i % 4 == 3)
  559.             printf(" ");
  560.         
  561.         if (i % 32 == 31)
  562.             printf("\n");
  563.         }
  564.     if (i % 32 != 0)
  565.         printf("\n");
  566.     }
  567.  
  568. #ifndef THINK_C
  569. void ParseArgs(int argc, char **argv)
  570.     {
  571.     char type;
  572.     char *arg;
  573.     /*------- Get command line arguments ----------------*/
  574.         
  575.     type = ' ';
  576.     for (argv++, argc--; argc--; argv++)    /* skip av[0] */
  577.         {
  578.         arg = (char *) *argv;
  579.         
  580.         type = (arg[0] == '-') ? (char) arg[1] : type;
  581.         if (arg[0] == '-')
  582.             arg += 2;
  583.  
  584.         switch (type)
  585.  
  586.             {
  587.             case 'f' :            /* set the tracefile name */
  588.                 if  (*arg == 0)
  589.                     break;
  590.                 (void) strcpy(gFileName, arg);
  591.                 c2pstr(gFileName);
  592.                 break;        
  593.  
  594.             case ' ':
  595.                 break;
  596.             case 'q' : gVerboseMode = false;
  597.                 break;
  598.             default:
  599.                 (void) printf("DumpTracks: illegal option [%c]\n", (char) type);
  600.                 (void) printf("format DumpTracks [ -f tracefilename] [-q] \n");
  601.                 exit(3);
  602.  
  603.             }
  604.         }
  605.  
  606.     return;
  607.     
  608.     }
  609. #endif
  610.  
  611. // Prints StackPeek data
  612. void PrintFmt01(char *fmt01Ptr)
  613. {
  614. char *stackdata;
  615. char *modulesym;
  616. char *callersym;
  617. snum modulelen;
  618. snum callerlen;
  619. char symbolName[256];
  620. char module[256], caller[256];
  621.  
  622.  
  623.     stackdata = fmt01Ptr;
  624.     modulesym = SkipPStr(stackdata);
  625.     callersym = SkipPStr(modulesym);
  626.     
  627.     CopyPStr(modulesym, module);
  628.     CopyPStr(callersym, caller);
  629.     
  630.     p2cstr(module);
  631.     p2cstr(caller);
  632.     
  633.     modulelen = *modulesym;
  634.     callerlen = *callersym;
  635.     
  636.     // if (0 ) printf("Decoding '%s' and '%s', %d, %d\n", module, caller, strlen(module), strlen(caller));
  637.     
  638.     (void) DecodeSym(symbolName, module, true, (Ptr) stackdata + 8);
  639.  
  640.     printf("'%s'\n", symbolName);
  641.  
  642.     (void) DecodeSym(symbolName, caller, true, (Ptr) stackdata + 8);
  643.     
  644.     printf("    called by '%s'\n", symbolName);
  645.  
  646.     return;
  647. }
  648.     
  649.  
  650.  
  651. void PrintFmt02(Ptr dataPtr, short dataLength)
  652. {
  653. int i;
  654. unsigned char ascii[18];
  655. unsigned char ebcdic[18];
  656. unsigned char c;
  657. BytePtr p;
  658. int pos;
  659. int linelen;
  660. int prtlen;
  661.     
  662.  
  663.     // Get length from LL field (length of print data does not include 2 bytes of LL)
  664.     
  665.     prtlen = dataLength;
  666.     
  667.     p = (BytePtr)dataPtr;
  668.     pos = 0;
  669.     
  670.     /* Here is a sample output line to line up the header text: */
  671.     /******"(00:  0000 0000 0D4C 4F4B  4920 5761 7220 524F    ……………LOKI War RO    IIIII<!.®ÄØ/ºÄ™!  ****/
  672.     printf("\n");    
  673.  
  674. #ifdef PRINTEBCIDIC
  675.     printf("                                                 ---- ASCII -----    ---- EBCDIC ----\n");
  676. #else
  677.     printf("                                                 ---- ASCII -----\n");
  678. #endif        
  679.  
  680.     while (prtlen > 0)
  681.         {
  682.  
  683.         printf("%02X:  ", (pos & 0x0ff));
  684.  
  685.         linelen = 16;
  686.         if (linelen > prtlen)
  687.             linelen = prtlen;
  688.  
  689.         for (i = 0; i < linelen; i++)
  690.         {
  691.             c = *p++;
  692.             pos++;
  693.             if ((c < 0x20) || (c == 0x7f))    // normally nonprinting characters
  694.                 ascii[i] = '.';    
  695.             else
  696.                 ascii[i] = c;
  697.                 
  698.             printf("%02X", c);
  699.             
  700.             if ((i == 7) || (i == 15))
  701.                 printf("  ");
  702.             else if ((i% 2) == 1)
  703.                 printf(" ");
  704.  
  705.         }
  706.         for (i = linelen; i < 16; i++)
  707.         {
  708.             printf("  ");
  709.             if ((i == 7) || (i == 15))
  710.                 printf("  ");
  711.             else if ((i% 2) == 1)
  712.                 printf(" ");
  713.         }            
  714.  
  715.         CopyEbcdicToAscii(ascii, ebcdic, linelen);
  716.         ascii[linelen] = ' ';
  717.         ebcdic[linelen] = ' ';
  718.         for (i = (linelen + 1); i < 17; i++)
  719.             {
  720.             ascii[i] = ' ';
  721.             ebcdic[i] = ' ';
  722.             }
  723.         ascii[17] = 0;
  724.         ebcdic[17] = 0;
  725. #ifdef PRINTEBCIDIC
  726.         printf("  %s   %s\n", ascii, ebcdic);
  727. #else
  728.         printf("  %s\n", ascii);
  729. #endif        
  730.         prtlen -= linelen;
  731.         
  732.         }
  733.  
  734. return;
  735.     
  736. }
  737.     
  738.  
  739. void PrintFmt04(long dataLong)
  740. {
  741. char     data1, data2, data3, data4;
  742.     data1 = (dataLong >> 24) & 0x0ff;
  743.     if ((data1 < 0x20) || (data1 == 0x7f))    // normally nonprinting characters
  744.         data1 = '.';    
  745.     data2 = (dataLong >> 16) & 0x0ff;
  746.     if ((data2 < 0x20) || (data2 == 0x7f))    // normally nonprinting characters
  747.         data2 = '.';    
  748.     data3 = (dataLong >> 8) & 0x0ff;
  749.     if ((data3 < 0x20) || (data3 == 0x7f))    // normally nonprinting characters
  750.         data3 = '.';    
  751.     data4 = dataLong & 0x0ff;
  752.     if ((data4 < 0x20) || (data4 == 0x7f))    // normally nonprinting characters
  753.         data4 = '.';    
  754.     printf("DATA = 0x%08X   #%d    '%c%c%c%c'\n", 
  755.      dataLong, dataLong, data1, data2, data3, data4);
  756. }
  757.  
  758. // Format of data is:
  759. // Length long word + Data [length bytes]
  760. void PrintFmt05(BytePtr data)
  761. {
  762. long *dataLong;
  763.  
  764.     dataLong = (long *)data;
  765.     data += 4;    // skip past the long
  766.     p2cstr(data);
  767.     printf("'%s'  %-5ld         0x%-8lX\n",
  768.         data, *dataLong, *dataLong);
  769.     c2pstr(data);
  770.     // PrintFmt04(*dataLong);
  771. }
  772.  
  773. //    Format of dataPtr is
  774. //        Length long [], Data [length bytes], PStr [Type Name]
  775.  
  776. void PrintFmt06(BytePtr data)
  777. {
  778. BytePtr typeStr, result;
  779. long *length;
  780. long    extraData;
  781.  
  782.     length = (long *)data;
  783.     data += 4;    // skip past the long
  784.     typeStr = data + *length;
  785.  
  786.     result = PrettyDump(data, typeStr);
  787.     extraData = (long)result - (long)typeStr;
  788.  
  789.  
  790.     if (result == nil)
  791.         {
  792.             // printf("Data Type Not Found.  Printing as data\n");
  793.             PrintFmt02(data, *length);
  794.         }
  795.     else
  796.     if (extraData < 0)
  797.     {
  798.         printf("••• Not enough data sent.  Some data is invalid •••\n");
  799.     }
  800.     
  801.     else
  802.     if (result-typeStr > 0)
  803.         {
  804.             printf("Dumping extra data...\n");
  805.             PrintFmt02(result, extraData);
  806.         }
  807.     // Check here later for extra data appended...  (that didn't fit in the record)
  808. }
  809.  
  810.  
  811. void PrintRecord(snum length)
  812.     {
  813. register NewRecordTemplate    *template;
  814. long dataLong;
  815. Str255    maskName;
  816. BytePtr dataStart;
  817.  
  818.     if (length >= 4)
  819.         {
  820.         template = (NewRecordTemplate *)gReadBuff;        
  821. #ifdef    TEST
  822.         printf("template->length %d\n", template->length);
  823.         printf("template->diagID %d\n", (short) template->diagID);
  824.         printf("template->partCode %d\n", (short) template->partCode);
  825.         printf("template->formatID %d\n", (short) template->formatID);
  826. //        printf("template->timestamp %ld\n", template->timeStamp );        
  827. #endif
  828.  
  829.         GetIndString(maskName, kMaskStringListID, (template->diagID & 0x7F) + 1);// Get String list name.
  830.         //  +1 because mask numbers start at 0, str#'s start at 1
  831.         
  832.         //
  833.         // Either DiagID is out of range or it is a new trace DiagID that has 
  834.         // not been added to the STR# resource in cdev.r
  835.         //
  836.         if (maskName[0] == 0)        // Perhaps out of range or STR# list not there...
  837.             strcpy((char *)maskName,(char *)"\p ???");
  838.  
  839.         if (template->partCode == 0)    
  840.         {
  841.             lastDiagID = template->diagID;    
  842.             p2cstr(maskName);
  843.             if (gVerboseMode)    printf("\n++ Trace Record ");
  844.             if (!gVerboseMode) printf("\n\n");
  845.             if (gVerboseMode)    PrintTimeAndDate(template->timeStamp);
  846.             if (gVerboseMode)    printf(" ++\n++ DiagID %02d ( %s ) ++\n", template->diagID, maskName);
  847.             if (0) printf("Format ID = %d\n", (short) template->formatID);
  848.         }
  849.         else
  850.             if (template->diagID != lastDiagID)    // First partCode must be zero
  851.                 printf(" ••• Trace partCode 0 expected •••\n");
  852.  
  853.         if (gVerboseMode)    printf("(%3d-%2d) ",(short) template->diagID & 0x7f,(short)template->partCode & 0x7f);
  854.  
  855.         dataStart = (BytePtr)template;
  856.         dataStart += sizeof(template);
  857.  
  858.         dataStart  = &template->formatID;
  859.         dataStart++;
  860.                 
  861.         switch (template->formatID)
  862.             {
  863.           case 0x00:
  864.                 printf("••• Data Lost Record •••\n");
  865.             break;
  866.           case 0x01:
  867.               if (gVerboseMode)    printf("STACKPEEK\n");
  868.             PrintFmt01(dataStart);
  869.             break;
  870.             
  871.           case 0x02:
  872.             if (gVerboseMode)    printf("DATA  ");        
  873.             // Length of Template ---  sizeof(template) -2 -- was 12 prior..
  874.               PrintFmt02(dataStart, template->length - 10); // 10  = Length of template!
  875.             break;
  876.          
  877.           case 0x03:
  878.               {
  879.             char *bytePtr;
  880.                 bytePtr = dataStart;
  881.                 // bytePtr++;
  882.                 if (gVerboseMode)    printf("PSTR \n");
  883.             
  884.               p2cstr(bytePtr);
  885.             printf("\"%s\"\n", bytePtr);
  886.             c2pstr(bytePtr);
  887.             }
  888.             break;
  889.         
  890.            case 0x04:
  891.             if (gVerboseMode)    printf("LONG \n");
  892.             dataLong = *(long *)dataStart;
  893.             PrintFmt04(dataLong);
  894.             break;
  895.         
  896.           case 0x05: 
  897.             if (gVerboseMode)    printf("PSTR + LONG \n");
  898.               PrintFmt05(dataStart);
  899.             break;
  900.         
  901.           case 0x06:
  902.               if (gVerboseMode) printf("FORMATTED TYPE DUMP\n");
  903.             PrintFmt06(dataStart);
  904.             break;
  905.             
  906.           default:
  907.               printf("•••• Unknown FormatID %d ••••\n", (short)template->formatID);        
  908.             break;
  909.             }
  910.         
  911.         // printf("\n");        // Space in between part codes....
  912.         }
  913.  
  914.     return;
  915.     
  916.     }
  917.  
  918. void PrintTimeAndDate(long    timestamp)
  919. {
  920. Str31    dateStr,timeStr;
  921.     IUDateString(timestamp, abbrevDate, dateStr);
  922.     p2cstr(dateStr);
  923.     IUTimeString(timestamp, true, timeStr);
  924.     p2cstr(timeStr);
  925.     printf("%s at %s",timeStr,dateStr);
  926. }
  927.  
  928.  
  929. snum ReadFileRecords(short refNum)
  930. {
  931. snum result;
  932. shex recordSize;    // Size of the current trace record being read
  933. long readAmount;    // Number of bytes to read from file
  934. long lostAmount;    // Number of bytes of record that will not fit in buffer
  935. Boolean gotLength;    // true if we read the length field
  936.     
  937.     // While no errors, retrieve trace records...
  938.     
  939.     result = 0;
  940.     
  941.     while (result == noErr)
  942.         {
  943.         
  944.         // Read in the record length field (2 bytes):
  945.         
  946.         gotLength = false;
  947.         
  948.         readAmount = 2;
  949.         result = FSRead(refNum, &readAmount, (Ptr) gReadBuff);
  950.         
  951.         if ((result == noErr) && (readAmount != 2))
  952.             result = paramErr; // use this error to flag this unexpected condition
  953.         else
  954.             {
  955.             gotLength = true;
  956.             
  957.             // Read in the remainder of this record:
  958.             // (Do not read in more than the buffer will hold)
  959.             
  960.             recordSize = *((shex *) gReadBuff);
  961.             readAmount = recordSize - 2;
  962.             
  963.             if (readAmount > gReadBuffSize)
  964.                 {
  965.                 lostAmount = readAmount - gReadBuffSize;
  966.                 readAmount = gReadBuffSize;
  967.                 }
  968.             else
  969.                 lostAmount = 0;
  970.  
  971.             result = FSRead(refNum, &readAmount, ((Ptr) gReadBuff) + 2);
  972.  
  973.             // If the trace record was too big for the buffer, move file mark past
  974.             // the end of this record so the next read will get th next record...
  975.             
  976.             if ((result == noErr) && (lostAmount != 0))
  977.                 result = SetFPos(refNum, fsFromMark, lostAmount);
  978.             
  979.             // Print this record:
  980.             
  981.             if (result == noErr)
  982.                 PrintRecord(readAmount + 2);
  983.             
  984.             }
  985.         }
  986.     
  987.     // If the error was end-of-file reached while reading length, then return noErr
  988.     
  989.     if ((result == eofErr) && ! gotLength)
  990.         result == noErr;
  991.     
  992.     return(result);
  993.     
  994.     }
  995.  
  996. Str31    gKnownTypeList[] = {"\pByte", "\pWord", "\pLong", "\pSignedByte", "\pSignedWord", "\pSignedLong", 
  997. "\pUnsignedByte", "\pUnsignedWord", "\pUnsignedLong", "\pBoolean", "\ppString", "\pcString", 
  998. "\pText", "\pSkip", "\pAlign", "\pHandle", "\pPointer"};    
  999.  
  1000. enum {kByte, kWord, kLong, kSignedByte, kSignedWord, kSignedLong, kUnsignedByte, kUnsignedWord, kUnsignedLong, kBoolean, kpString,
  1001. kcString, kText, kSkip, kAlign, kHandle, kPointer, kNumTypes};
  1002.  
  1003.  
  1004.  
  1005. BytePtr    gDataPtr;
  1006. short gNumResources;
  1007. TmplHandle    gDataHandle[10];
  1008.  
  1009.  
  1010. BytePtr SkipPStr(BytePtr str)
  1011. {
  1012. short num, x;
  1013.     num = (short) *str;
  1014.     str++;
  1015.     for (x=0;x<num;x++)
  1016.         str++;
  1017.     return (str);
  1018. }
  1019.  
  1020.  
  1021. // Note:  gKnownTypeList is defined above, and contains a list of the basic
  1022. // type definitions, such as Long, Boolean, etc...
  1023. BytePtr    DumpMemory (BytePtr wh, char *type)
  1024. {
  1025. short x;
  1026. long    *lp;
  1027. short    *sp;
  1028.     lp = (long *)wh;
  1029.     sp = (short *)wh;
  1030.     
  1031.     if (wh == nil) {printf("DumpMemory err:  data ptr = nil\n");return nil;}
  1032.     
  1033.     x = -1;
  1034.     
  1035.     if (type[1] == '^') x = kPointer;
  1036.     if (type[2] == '^') x = kHandle;
  1037.     
  1038.     if (x == -1)    // if not a pointer (^xxx) or handle (^^dataBlock)
  1039.     {
  1040.         for (x=0;x<kNumTypes;x++)
  1041.             if (strcmp(type, (char *)gKnownTypeList[x]) == 0) break;
  1042.     } 
  1043.     
  1044.     switch (x)
  1045.     {
  1046.         case kByte:     
  1047.         case kSignedByte:     
  1048.             printf("%-02d  ", *wh);wh+=1;break;
  1049.         case kWord: 
  1050.         case kSignedWord: 
  1051.             printf("%-6d ", *sp);wh+=2;break;
  1052.         case kSignedLong:     
  1053.         case kLong:     
  1054.             printf("%-08ld ", *lp);wh+=4;break;        
  1055.         case kUnsignedByte:     
  1056.             printf("0x%-02X  = '%c'", *wh, *wh);wh+=1;break;        
  1057.         case kUnsignedWord: 
  1058.             printf("0x%-6X ", *sp);wh+=2;break;
  1059.         case kUnsignedLong:     
  1060.             printf("0x%-08ld ", *lp);wh+=4;break;
  1061.         case kBoolean:     
  1062.             if (*wh)
  1063.                 printf("true ");
  1064.             else
  1065.                 printf("false ");
  1066.             wh+=1;break;        // Check this...
  1067.  
  1068.         case kpString:     
  1069.             {
  1070.                 short len = *wh,c;
  1071.                 
  1072.                 wh++;
  1073.                 printf("pString = '");
  1074.                 for (c=0;c<len;c++)
  1075.                     printf("%c", *wh++);
  1076.                 printf("'");
  1077.                 break;
  1078.             }
  1079.         case kcString:     
  1080.             {
  1081.                 printf("cString = '");
  1082.                 while (*wh)
  1083.                     printf("%c", *wh++);
  1084.                 printf("'");
  1085.                 break;
  1086.             }
  1087.     
  1088.         case kText:  break;        // Not supported... 
  1089.         
  1090.         case kSkip:
  1091.             printf("0x%-4X", *sp);
  1092.             wh+=2;
  1093.             break;
  1094.  
  1095.         case kAlign: 
  1096.         printf("ALIGN byte (%d)", *wh);
  1097.         wh++;break;
  1098.  
  1099.         case kHandle:     
  1100.             printf("0x%-08lX ", *lp);wh+=4;break;
  1101.             
  1102.         case kPointer:     
  1103.             printf("0x%-08lX ", *lp);wh+=4;break;
  1104.  
  1105.         case kNumTypes:     // Specified template was not of standard type....
  1106.             if (0)
  1107.             {
  1108.                 p2cstr(type);
  1109.                 printf("Looking for type '%s'\n", type);
  1110.                 c2pstr(type);
  1111.             }
  1112.             wh = DMWithTemplate(wh, type);
  1113.             break;    
  1114.         default :
  1115.             p2cstr(type);
  1116.             printf("DT Err: Unknown type: '%s'\n", type);
  1117.             c2pstr(type);
  1118.             break;
  1119.     };
  1120.     return wh;
  1121. }
  1122.  
  1123.  
  1124. // Displays info on template, and points to the next one
  1125. BytePtr HandleField(BytePtr field, Boolean printOn)
  1126. {
  1127. short *count, r;
  1128. char *fieldName, *type;
  1129.  
  1130.     if (printOn) printf("    '");
  1131.     fieldName = field;
  1132.     if (printOn)    PrintPStr(fieldName);
  1133.     field = SkipPStr(field);
  1134.     if (printOn) printf("'    ");
  1135.     
  1136.     type = field;
  1137.     field = SkipPStr(field);
  1138.     
  1139.     // if (printOn) (void) PrintPStr(type);
  1140.     // if (printOn) printf ("  ");
  1141.     count = (short *) field;
  1142.     
  1143.     
  1144.     field += 2;
  1145.     
  1146.     if (printOn) 
  1147.     for (r = 0; r < *count; r++)    
  1148.         {
  1149.             if (gDataPtr == nil) printf("Type dump err..\n");    // doesnt happen 
  1150.             gDataPtr = DumpMemory(gDataPtr, type);    // Call recursivly
  1151.             if (gDataPtr == nil) {printf("DumpMemory Error\n");break;}
  1152.         }
  1153.     if (printOn) printf("\n");    
  1154.     return field;
  1155. }
  1156.  
  1157. // Displays info on template, and points to the next one
  1158. BytePtr HandleTemplate(BytePtr    tmpl, Boolean printOn)
  1159. {
  1160. short     x, *fields;
  1161. char *templateName;
  1162.  
  1163.     templateName = tmpl;
  1164.     tmpl = (char *) SkipPStr(tmpl);
  1165.  
  1166.     if (printOn) 
  1167.     {
  1168.         (void) PrintPStr(templateName);        // Special Type Name
  1169.         printf("\n");
  1170.     }
  1171.     fields = (short*) tmpl;
  1172.     tmpl += 2;
  1173.  
  1174.     // I assume there will be no data structrures with more than 100 fields...
  1175.     if (*fields > 100) {printf("Type Dump Error.  %d is too many fields (>100) \n", *fields);return nil;}
  1176.     
  1177.     for (x=0;x < *fields;x++)
  1178.         tmpl = HandleField(tmpl, printOn);
  1179.     return tmpl;    // this now points to the next template...
  1180. }
  1181.  
  1182.  
  1183. short TypeDumpSetUp(short SysFolderRefNum)
  1184. {
  1185. short x;
  1186. short err;
  1187. short prefsResRefNum;
  1188.  
  1189.     prefsResRefNum = OpenRFPerm("\pDebugger Prefs", SysFolderRefNum, fsRdWrPerm);
  1190.     err = ResError();
  1191.     if (err != noErr) prefsResRefNum = 0;
  1192.     gNumResources = CountResources('mxwt');
  1193.     if (gNumResources >10) gNumResources = 10;    /* Heaven forbid they have more... */
  1194.     
  1195.     if (gNumResources > 0)
  1196.     for (x=0;x<gNumResources;x++)
  1197.     {
  1198.         gDataHandle[x] = (TmplHandle)GetIndResource('mxwt', x+1);
  1199.         
  1200.         // if (gDataHandle) printf("Loaded mxwt resource\n");
  1201.         
  1202.         if (gDataHandle[x] == nil) {printf("Failed to load resource\n");gNumResources = x-1;return false;}
  1203.         DetachResource((Handle)gDataHandle[x]);
  1204.         HLock((Handle)gDataHandle[x]);
  1205.     }
  1206.     if (prefsResRefNum)
  1207.         CloseResFile(prefsResRefNum);        
  1208.     return x;
  1209. }
  1210.  
  1211. void TypeDumpCloseDown()
  1212. {
  1213. short x;
  1214.     for (x=0;x<gNumResources;x++)
  1215.     {
  1216.         HUnlock((Handle)gDataHandle[x]);
  1217.         DisposHandle((Handle)gDataHandle[x]);
  1218.         gDataHandle[x] = nil;
  1219.     }
  1220. }
  1221.  
  1222. ComparePStr(char *a, char *b)
  1223. {
  1224. char len, x;
  1225.     len = *a;
  1226.     for (x=0;x<=len;x++)
  1227.         if (*a++ != *b++) return false;
  1228.     return true;
  1229. }
  1230.  
  1231.  
  1232. BytePtr DMWithTemplate (BytePtr wh, char *searchType)
  1233. {
  1234. short     numTemplates;
  1235. short     x, t;
  1236. BytePtr        tmpl;
  1237. Boolean PrintRecord;
  1238.  
  1239.     gDataPtr = wh;
  1240.     for (t=0;t<gNumResources;t++)
  1241.     {
  1242.         numTemplates = (**gDataHandle[t]).NumTemplates;
  1243.         tmpl = (BytePtr) &(**gDataHandle[t]).FirstTemplate;
  1244.         
  1245.         for (x=0;x < numTemplates;x++)        // numTemplates
  1246.             {
  1247.                 PrintRecord = ComparePStr(searchType, tmpl);        /* Is this it?  If so, print it out.. */
  1248.                 tmpl = HandleTemplate(tmpl, PrintRecord);
  1249.                 if (PrintRecord) return gDataPtr;
  1250.             }
  1251.     }
  1252.     return nil;
  1253. }
  1254.  
  1255. BytePtr PrintPStr(BytePtr str)
  1256. {
  1257. register short num, x, i;
  1258.     num = (short) *str;
  1259.     str++;
  1260.     for (x=0;x<num;x++)
  1261.         printf("%c", *str++);
  1262.     for (i=x;i< 17;i++)
  1263.         printf(" ");
  1264.     return (str);
  1265. }
  1266.  
  1267. BytePtr PrettyDump(BytePtr    data, BytePtr typeString)
  1268. {
  1269. BytePtr    found;
  1270.     found = DumpMemory((BytePtr)data, typeString);
  1271.     if (found == nil) 
  1272.         {
  1273.             p2cstr(typeString);
  1274.             printf("'%s' Unknown Data Type.", typeString);
  1275.             c2pstr(typeString);
  1276.         }
  1277.     printf("\n");
  1278.     return found;
  1279. }
  1280.  
  1281.